package com.cube.backribs.model;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONObject;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class GoogleMapkiUtil {
    /**
     * ��占썸�⑨옙占쎈��占썲��占� ����占쎌�듭��占쏙옙����占쏙옙 ����占쏙옙����由� Intent Extra ����占�
     */
    final static public String RESULT = "result";
    /**
     * 嶺�占썲��占� ��占썲������繹�占썲����占쏙옙 ����占쏙옙����占쏙���筌�����占쏙옙 ��占쏙옙占쏙옙占� Intent Extra �띰옙��占�
     */
    final static public String FAIL_MAP_RESULT = "fail_map_result";
    /**
     * ����占썲����占쏙옙 Intent Extra �띰옙��占�
     */
    final static public String ERROR_RESULT = "error_result";
    /**
     * ������占썩�⑥�� Intent Extra �띰옙��占�
     */
    final static public String SUCCESS_RESULT = "success_result";
    /**
     * ����占쏙옙�띰옙��占� 嶺�占썲��������占� Intent Extra �띰옙��占�
     */
    final static public String TIMEOUT_RESULT = "timeout_result";
    /**
     * Log Client
     */
    final static public String TAG_CLIENT = "client";
    /**
     * Log Server
     */
    final static public String TAG_SERVER = "server";

    /**
     * ��占썸�⑨옙占쏙옙 String �띰옙��占�
     */
    public String stringData;

    // 嶺�占썲�������뤄옙 ��占썲������繹�占� 占쏙옙熬��ㅿ옙�ル���� ����占썬����占쏙옙����援�
    private SearchThread searchThread;
    // ��占썸�⑨옙占쏙옙 ����占쎌�듭��占쏙옙����占쏙옙 ����占쏙옙����由� ����占썲����援뜹����占쏙옙
    private Handler resultHandler;
    // HttpClient
    private HttpClient httpclient;

    /**
     * HttpClientUtil Constructor
     */
    public GoogleMapkiUtil() {

    }

    /**
     * q : 검색어를 지정한다(필수)
     * near : 특정 주소의 근처를 검색하려면 지정한다. (보통 Address
     * address.getAddressLine(0)로 입력함) output : 결과를 어떤 형식으로 받을지 결정한다(json, html, kml 등등)
     * mrt : 결과 범위 결정(all:전부 검색, yp: 비지니스 영역 검색, websearch:웹 검색 등등) hl : 언어 
     * radius : 검색반경 설정(near 가 없으면 소용없는 듯), miles = kilometers/1.60934
     * num : 결과 갯수
     * start : 결과의 시작 번호, 10개 다음 num개의 결과를 알고 싶다면 start=10이라고 지정한다. (0부터 시작하는 값)
     */
    public void requestMapSearch(Handler _resultHandler, String searchingName,
            String nearAddress) {
        resultHandler = _resultHandler;

        List<BasicNameValuePair> qparams = new ArrayList<BasicNameValuePair>();
        qparams.add(new BasicNameValuePair("q", searchingName));
        qparams.add(new BasicNameValuePair("output", "json"));
        qparams.add(new BasicNameValuePair("mrt", "yp"));
        qparams.add(new BasicNameValuePair("hl", "ko"));
        qparams.add(new BasicNameValuePair("radius", "18.641"));
        qparams.add(new BasicNameValuePair("num", "5"));
        qparams.add(new BasicNameValuePair("near", nearAddress));

        searchThread = new SearchThread(
                qparams.toArray(new BasicNameValuePair[qparams.size()]));
        searchThread.start();
    }

    // Thread for Searching Map
    private class SearchThread extends Thread {
        private String parameters;

        public SearchThread(NameValuePair[] _nameValues) {
            parameters = encodeParams(_nameValues);
        }

        public void run() {
            httpclient = new DefaultHttpClient();

            try {
                HttpGet get = new HttpGet();
                get.setURI(new URI("http://maps.google.co.kr?" + parameters));

                Log.i(TAG_CLIENT, "http://maps.google.co.kr?" + parameters);

                // 5占싸우�� ����占쎈����占쏙옙����占쏙옙�띰옙��占� ����������占썬������占썲����占쏙옙
                HttpParams params = httpclient.getParams();
                params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
                        HttpVersion.HTTP_1_1);
                HttpConnectionParams.setConnectionTimeout(params, 10000);
                HttpConnectionParams.setSoTimeout(params, 10000);

                httpclient.execute(get, responseSearchHandler);
            } catch (ConnectTimeoutException e) {
                Message message = resultHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(RESULT, TIMEOUT_RESULT);
                message.setData(bundle);
                resultHandler.sendMessage(message);
                stringData = e.toString();
            } catch (Exception e) {
                Message message = resultHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(RESULT, ERROR_RESULT);
                message.setData(bundle);
                resultHandler.sendMessage(message);
                stringData = e.toString();
            } finally {
                httpclient.getConnectionManager().shutdown();
            }
        }
    }

    // ����占쏙옙����占썬��占썽��占썼��節���獄��듭��占쏙옙 GET ����占쏙옙����占쏙옙����占쏙옙�β�쎌�� 占쎌��占쏙옙��湲대뭄��占�
    private String encodeParams(NameValuePair[] parameters) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < parameters.length; i++) {
            sb.append(parameters[i].getName());
            sb.append('=');
            sb.append(parameters[i].getValue().replace(" ", "+"));

            if (i + 1 < parameters.length) {
                sb.append('&');
            }
        }

        return sb.toString();
    }

    // 嶺�占썲�������뤄옙��占썲������繹�占� ��占썸�⑨옙占쏙옙 ����占썲����援뜹����占쏙옙
    private ResponseHandler<String> responseSearchHandler = new ResponseHandler<String>() {

        private String jsonString;

        @Override
        public String handleResponse(HttpResponse response)
                throws ClientProtocolException, IOException {
            StringBuilder sb = new StringBuilder();

            try {
                InputStreamReader isr = new InputStreamReader(response
                        .getEntity().getContent(), "EUC-KR");
                BufferedReader br = new BufferedReader(isr);

                for (;;) {
                    String line = br.readLine();

                    if (line == null) {
                        break;
                    }

                    sb.append(line + '\n');
                }

                br.close();

                String jsonString = sb.toString().substring(9);// while(1);
                                                               // 占쎌��占쏙옙占�
                                                               // 嶺�占썲������占쏙옙�ル����
                Log.d(TAG_SERVER, jsonString);

                JSONObject jj = new JSONObject(jsonString);
                JSONObject overlays = jj.getJSONObject("overlays");
                JSONArray markers = overlays.getJSONArray("markers");

                if (markers != null) {
                    ArrayList<String> searchList = new ArrayList<String>();
                    String lat, lon;
                    String address;

                    for (int i = 0; i < markers.length(); i++) {
                        address = markers.getJSONObject(i).getString("laddr");
                        lat = markers.getJSONObject(i).getJSONObject("latlng")
                                .getString("lat");
                        lon = markers.getJSONObject(i).getJSONObject("latlng")
                                .getString("lng");
                        // ��占쏙옙源�占쏙옙, ����占쏙옙����占�, ��占쏙옙占썹�뤄옙 ����占쏙옙����占쏙옙�β�쎌�� ����������占쏙�����占�.
                        searchList.add(address);
                        searchList.add(lat);
                        searchList.add(lon);
                    }

                    Message message = resultHandler.obtainMessage();
                    Bundle bundle = new Bundle();
                    bundle.putString(RESULT, SUCCESS_RESULT);
                    bundle.putStringArrayList("searchList", searchList);
                    message.setData(bundle);
                    resultHandler.sendMessage(message);
                } else {
                    Message message = resultHandler.obtainMessage();
                    Bundle bundle = new Bundle();
                    bundle.putString(RESULT, FAIL_MAP_RESULT);
                    message.setData(bundle);
                    resultHandler.sendMessage(message);

                    stringData = "JSon >> \n" + sb.toString();
                    return stringData;
                }
            } catch (Exception e) {
                Message message = resultHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putString(RESULT, ERROR_RESULT);
                message.setData(bundle);
                resultHandler.sendMessage(message);

                stringData = "JSon >> \n" + e.toString();
                return stringData;
            }

            stringData = jsonString;
            return stringData;
        }
    };
}
